/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pkg1ifxServidorTcp;

import pkg1ifxArchivos.cIfxProtocolo;
import pkg1ifxArchivos.cifxDatosArchivo;
import java.net.*;
import java.io.*;
import pkg1ifxArchivos.cifxLogs;

/**
 *
 * @author strailaparicio
 */
public class cIfxClientesCon extends Thread {
    protected  Socket puerto = null;
    protected boolean conectado=false;
    protected cIfxServidor oservirdor = null;
    //private Object ofrmgral = null;
    protected String snombreagente="";
    protected String sdireccionipagenete="";
    protected String sultimomsj="";
    protected int nllave=0;
    protected cIfxDatosMSJ omsj=new cIfxDatosMSJ();
    protected cifxDatosArchivo odarchivo = new cifxDatosArchivo();
    protected int ntamanoenvio=1024;
    protected cifxLogs olog = new cifxLogs();
    protected String scadenaperdida="";
    
    //Variables para consolaprivate javax.swing.JList lstMe

    

    //public cIfxClientesCon (Socket socket,frmGRal ofrmppal,cIfxServidor oservirdor)
    public cIfxClientesCon (Socket socket,cIfxServidor servirdor,cifxLogs log)
    {
        super("cIfxClientesCon");
        puerto = socket;
        //this.ofrmgral= ofrmppal;
        this.oservirdor=servirdor;
        olog=log;
    }

    public int getLlave()
    {
        return nllave;
    }
    public void setLlave(int nkey)
    {
        nllave=nkey;
        //System.out.println("Agente creado con la nkey - " + this.nllave);
    }
    
    public String getAgenteIP()
    {
        return sdireccionipagenete;
    }
    public String getNombreAgente()
    {
        return snombreagente;
    }
    public String getUltimoMsj()
    {
        return sultimomsj;
    }
    
    public Socket getPuerto()
    {
        return puerto;
    }
//
    //
    //
    
    
    private synchronized void runNEW()
    {
        try {
                //Variable para controlar que acaba de salir de un IFX-Put
                // "+sdireccionipagenete+"
                boolean bSalirNo=false;
                //Activo los flujos para entrada salida de datos
                PrintWriter out = new PrintWriter(puerto.getOutputStream(), true);
                BufferedReader in = new BufferedReader(
                                        new InputStreamReader(puerto.getInputStream()));
                //Variables para el manejo de de los mensajes de entrada salida
                sdireccionipagenete=puerto.getInetAddress().toString();
                olog.outMensaje("cIfxClientesCon: Entrando conexion con IP:"+sdireccionipagenete);

                String inputLine, outputLine;
                cIfxProtocolo kkp = new cIfxProtocolo();
                outputLine = kkp.procesarES("IFX-Saludo");
                out.println(outputLine);

                while (true) {

                    if(scadenaperdida.length()>0)
                    {
                       inputLine=scadenaperdida;
                       scadenaperdida="";
                    }
                    else
                    {
                        inputLine = in.readLine();
                        if(inputLine == null)
                            break;
                    }


                    olog.outMensaje("cIfxClientesCon.run(): "+sdireccionipagenete+" Entrando Comando: "+inputLine);
                    outputLine = kkp.procesarES(inputLine);

                    if(outputLine.equals("IFX-DatosAgente"))
                    {
                        //puerto.
                        snombreagente=kkp.getNombreAgente();
                        //Strail solo para la consola ofrmgral.setAgenteNuevoEnLista(kkp.getNombreAgente()+" | " +sdireccionipagenete);

                    }
                    else if(outputLine.equals("IFX-Servidor"))
                    {
                        sultimomsj="IFX-Servidor";

                    }
                    else if(outputLine.equals("IFX-Cmd"))
                    {
                        sultimomsj=kkp.getUltimoMsj();
                        cifxCmd ocmd = new cifxCmd(sultimomsj);
                        ocmd.start();

                        while(!ocmd.HayResultados())
                            System.out.print("");

                        outputLine=ocmd.getResultados()+ "IFX-Cmd ("+ocmd.getNomFileResult()+")";
                        //outputLine+="\n";

                    }
                    else if(outputLine.equals("IFX-Msj"))
                    {
                        //cIfxDatosMSJ omsj=new cIfxDatosMSJ();
                        //kkp.getUltimoMsj().
                        sultimomsj=kkp.getUltimoMsj();
                        omsj.convCadEnMsj(sultimomsj);
                        //if(trabajarconconsola)
                        //    setMsjAgente(omsj);

                    }

                    else if(outputLine.equals("IFX-Mensaje"))
                    {
                        sultimomsj=kkp.getUltimoMsj();
                        //ofrmgral.setMsjConsola(kkp.getUltimoMsj());

                    }
                    else if(outputLine.equals("IFX-Put"))
                    {
                        //IFX-Put nombre archivo|tamaño|path destino
                        sultimomsj=kkp.getUltimoMsj();
                        odarchivo.ConvCad(sultimomsj);
                        //Hago el cambio de funciones para la prueba
                        //leerGuardarBytes();
                        leer_BytesGuardar();

                         olog.outMensaje("cIfxClientesCon.run(): "+sdireccionipagenete+"Se ha terminado de leer archivo");

                        outputLine="";
                        //Probando a desconectar para evitar problemas
                        break;
                       

                    }
                    else if(outputLine.equals("IFX-Get"))
                    {
                        //IFX-Get nombre archivo
                        sultimomsj=kkp.getUltimoMsj();

                        leerEnviarBytes(sultimomsj.trim(),getPuerto());

                        olog.outMensaje("cIfxClientesCon.run(): "+sdireccionipagenete+"Se ha terminado de enviar archivo");
                        outputLine="";
                        //Probando a desconectar para evitar problemas
                        break;
                        
                    }
                    else if(outputLine.equals("IFX-putASCII"))
                    {
                        //IFX-Put nombre archivo|tamaño|path destino
                        sultimomsj=kkp.getUltimoMsj();
                        odarchivo.ConvCad(sultimomsj);
                        //Hago el cambio de funciones para la prueba
                        //leerGuardarBytes();
                        //Strail 08/08/2011 Comentario a la funcion de los ascii
                        //leer_BytesGuardarASCII();
                        //leer_BytesGuardarBlancoASCII();
                        leer_putASCII();

                         olog.outMensaje("cIfxClientesCon.run(): "+sdireccionipagenete+"Se ha terminado de leer archivo");

                        outputLine="";
                        //Probando a desconectar para evitar problemas
                        break;

                    }                        
                    else if(outputLine.equals("IFX-Desconectando ..."))
                    {
                        out.println(outputLine);
                        //olog.outMensaje("cIfxClientesCon: Desconectando IP:"+sdireccionipagenete);
                        outputLine="";
                        break;

                    }
                    else if(outputLine.equals("IFX-InfFile"))
                    {
                        sultimomsj=kkp.getUltimoMsj().trim();
                        
                        File forigen = new File(sultimomsj);
                        if(forigen.exists())
                        {
                            outputLine=String.valueOf(forigen.length());
                        }
                        else
                           outputLine="0"; 
                        //out.println(outputLine);
                        //olog.outMensaje("cIfxClientesCon: Desconectando IP:"+sdireccionipagenete);
                        //break;

                    }
                    //STR-Esta sentencia envia datos al cliente
                    olog.outMensaje("cIfxClientesCon.run(): "+sdireccionipagenete+" Enviandole Respuesta:"+outputLine);
                    if(outputLine.length()>0)
                    {
                        
                        out.println(outputLine);
                        out.flush();
                        break;
                    }


                    out.flush();

                }
                out.close();
                in.close();
                puerto.close();
                olog.outMensaje("cIfxClientesCon: Desconectando IP:"+sdireccionipagenete);
                oservirdor.QuieroSalir(nllave);

	}catch(SocketTimeoutException tex)
        {
            olog.outMensaje("cIfxClientesCon.run(): Time out :"+tex.getMessage());
            olog.outMensaje("cIfxClientesCon: Desconectando IP:"+sdireccionipagenete);
            oservirdor.QuieroSalir(nllave);
        }
        catch (IOException e) {
	    olog.outMensaje("cIfxClientesCon.run(): "+sdireccionipagenete+" ERROR:"+e.getMessage());
            oservirdor.QuieroSalir(nllave);
	}
    }
    

    
    @Override
    public void run()
    {
        runNEW();

    }

    private void LeerAdministrarLinea()
    {
        
    }
    
    protected synchronized void leer_putASCII()
    {
        InputStream sis;
        String stmp="";
        FileWriter fichero = null;
        PrintWriter pwtxt = null;
        try {
                sis = puerto.getInputStream();

                PrintWriter lout = new PrintWriter(puerto.getOutputStream(), true);
                BufferedReader lin = new BufferedReader(new InputStreamReader(puerto.getInputStream()));
                
                
                

                byte[] buffer=new byte[ntamanoenvio];
                int nread=0;
                long ntotalleido=0;
                //OutputStream fout = null;
                //String sSalir="";
                //Manejo de archivo en disco
                //Encoder.UTF_8;
                //InputStreamReader reader = new InputStreamReader
                        
                File fdestino = new File(odarchivo.getDestino());
                if(fdestino.exists())
                {

                    fichero = new FileWriter(fdestino);
                    pwtxt = new PrintWriter(fichero);
                        //Si el archivo existe abrirlo para agregar lo que falta
                        //si el tamaño del archivo es igual al que se va a transmitir?
                        //salir archivo ya existe y no se hace nada
                    if(fdestino.length()>=odarchivo.getTamanoArchivo())
                    {
                        //lout.println("IFX-putASCII existe");
                        olog.outMensaje("cIfxClientesCon.leer_putASCII:"+sdireccionipagenete+" YA EXISTE el archivo: "+odarchivo.getDestino());
                        //sis.close();
                        //lout.close();
                        //fout.close();
                        //return;
                        moverArchivoViejo(odarchivo.getDestino());
                        fdestino = new File(odarchivo.getDestino());
                    }
                    olog.outMensaje("cIfxClientesCon.leer_putASCII:"+sdireccionipagenete+" YA EXISTE el archivo pero incompleto: "+odarchivo.getDestino());
                    olog.outMensaje("cIfxClientesCon.leer_putASCII:"+sdireccionipagenete+" El tamaño actual es: "+fdestino.length());

                    fichero = new FileWriter(fdestino);
                    pwtxt = new PrintWriter(fichero);
                    //fout = new FileOutputStream(fdestino,true);
                    //lout.println("IFX-putASCII tamano:"+fdestino.length());
                    lout.println("IFX-putASCII tamano:0");
                    //Aqui me aseguro que el tamaño donde arranco es el del actual archivo
                    ntotalleido=fdestino.length();
                    //fdestino.

                }
                else
                {
                    fichero = new FileWriter(fdestino);
                    pwtxt = new PrintWriter(fichero);
                     //fout = new FileOutputStream(fdestino,true);
                     lout.println("IFX-putASCII tamano:0");

                }
                //OutputStream fout = new FileOutputStream(fdestino,true);
                lout.flush();    
                if(odarchivo.getTamanoArchivo()>0)
                {
                    olog.outMensaje("cIfxClientesCon.leer_putASCII:"+sdireccionipagenete+" Inicio guardar archivo :"+odarchivo.getDestino());
                    olog.outMensaje("cIfxClientesCon.leer_putASCII:"+sdireccionipagenete+" Tamaño archivo ->"+odarchivo.getTamanoArchivo());
                    int nlen=0;
                    String soriginal="";
                    long nprueba=0;

                    //while(((nread = sis.read(buffer))>0))
                    //while(((nread = sis.read(buffer))!=-1))
                    while((stmp=lin.readLine())!=null)    
                    {
                        
                        nread=stmp.getBytes("UTF8").length;
                        ntotalleido+=nread;
                        if(stmp.equals("IFX-putASCII TATAA"))
                        {
                            pwtxt.flush();
                            lout.println("IFX-putASCII TERMENI");

                            break;
                        }
                        else if(ntotalleido>odarchivo.getTamanoArchivo())
                        {
                            nread=nread-(int)(ntotalleido-odarchivo.getTamanoArchivo());
                            //int ndiff=quitarCRNL(buffer);
                            //stmp=new String(buffer,"UTF8");
                            //Esto es una prueba
                            stmp=stmp.replaceAll("\r\n", " \n");
                            //nread=stmp.getBytes("UTF8").length;
                            //if(ndiff>0)
                            //    nread=nread-ndiff;
                            //nread=stmp.getBytes("UTF8").length;
                            //fout.write(stmp.getBytes("UTF8"),0,nread);
                            pwtxt.println(stmp);
                            scadenaperdida=stmp.substring(nread+1);
                            //fout.flush();
                            pwtxt.flush();
                            lout.println("IFX-putASCII TERMENI");

                            break;
                        }
                        else if(ntotalleido==odarchivo.getTamanoArchivo())
                        {
                            //int ndiff=quitarCRNL(buffer);
                            //stmp=new String(buffer,"UTF8");
                            //Esto es una prueba
                            
                            stmp=stmp.replaceAll("\r\n", " \n");
                            
                            //nread=stmp.getBytes("UTF8").length;
                            //if(ndiff>0)
                            //    nread=nread-ndiff;
                            //nread=stmp.getBytes("UTF8").length;
                            //fout.write(stmp.getBytes("UTF8"),0,nread);
                            pwtxt.println(stmp);
                            //fout.write(stmp.getBytes("UTF8"));
                            //fout.write(buffer,0,nread);
                            pwtxt.flush();
                            lout.println("IFX-putASCII TERMENI");
                            break;
                        }
                        else
                        {
                            //int ndiff=quitarCRNL(buffer);
                            //stmp=new String(buffer,"UTF8");
                            //Esto es una prueba
                            stmp=stmp.replaceAll("\r\n", " \n");
                            //nread=stmp.getBytes("UTF8").length;
                            //if(ndiff>0)
                            //    nread=nread-ndiff;
                            //nread=stmp.getBytes("UTF8").length;
                            //fout.write(stmp.getBytes("UTF8"),0,nread);
                            pwtxt.println(stmp);
                        }
                        //Limpiando Buffer de datos para dejar en vacio.
                        //buffer=new byte[ntamanoenvio];

                    }
                    lout.flush();
                    //fout.flush();

                    olog.outMensaje("cIfxClientesCon.leer_putASCII:"+sdireccionipagenete+" FIN LEER Total Leido ->"+ntotalleido);
                    olog.outMensaje("cIfxClientesCon.leer_putASCII:"+sdireccionipagenete+" TAMAÑO Archivo Total Leido ->"+odarchivo.getTamanoArchivo());
                    //System.out.println("leerGuardarBytes - Termina guardar archivo");

                    //sis.close();
                    //lout.close();
                    //lin.close();
                }
                pwtxt.close();
        } catch (IOException ex) {
            //Logger.getLogger(cIfxClientesCon.class.getName()).log(Level.SEVERE, null, ex);
            olog.outMensaje("cIfxClientesCon.leer_putASCII(): ERROR:"+ex.getMessage());
        }
        catch (Exception ex)
        {
            olog.outMensaje("cIfxClientesCon.leer_putASCII(): ERROR:"+ex.getMessage());
        }
    }
    
    /**
     * Lee los archivos enviados por el cliente y los guarda en
     * hace el cambio de "\r\n" a " \n"
     */
    protected synchronized void leer_BytesGuardarBlancoASCII()
    {
                InputStream sis;
        String stmp="";
        try {
                sis = puerto.getInputStream();

                PrintWriter lout = new PrintWriter(puerto.getOutputStream(), true);
                //BufferedReader lin = new BufferedReader(new InputStreamReader(puerto.getInputStream()));

                byte[] buffer=new byte[ntamanoenvio];
                int nread=0;
                long ntotalleido=0;
                OutputStream fout = null;
                //String sSalir="";
                //Manejo de archivo en disco
                //Encoder.UTF_8;
                //InputStreamReader reader = new InputStreamReader
                        
                File fdestino = new File(odarchivo.getDestino());
                if(fdestino.exists())
                {
                        //Si el archivo existe abrirlo para agregar lo que falta
                        //si el tamaño del archivo es igual al que se va a transmitir?
                        //salir archivo ya existe y no se hace nada
                    if(fdestino.length()>=odarchivo.getTamanoArchivo())
                    {
                        //lout.println("IFX-putASCII existe");
                        olog.outMensaje("cIfxClientesCon.leer_BytesGuardarBlancoASCII:"+sdireccionipagenete+" YA EXISTE el archivo: "+odarchivo.getDestino());
                        //sis.close();
                        //lout.close();
                        //fout.close();
                        //return;
                        moverArchivoViejo(odarchivo.getDestino());
                        fdestino = new File(odarchivo.getDestino());
                    }
                    olog.outMensaje("cIfxClientesCon.leer_BytesGuardarBlancoASCII:"+sdireccionipagenete+" YA EXISTE el archivo pero incompleto: "+odarchivo.getDestino());
                    olog.outMensaje("cIfxClientesCon.leer_BytesGuardarBlancoASCII:"+sdireccionipagenete+" El tamaño actual es: "+fdestino.length());

                    fout = new FileOutputStream(fdestino,true);
                    lout.println("IFX-putASCII tamano:"+fdestino.length());
                    //Aqui me aseguro que el tamaño donde arranco es el del actual archivo
                    ntotalleido=fdestino.length();
                    //fdestino.

                }
                else
                {
                     fout = new FileOutputStream(fdestino,true);
                     lout.println("IFX-putASCII tamano:0");

                }
                //OutputStream fout = new FileOutputStream(fdestino,true);
                lout.flush();    
                if(odarchivo.getTamanoArchivo()>0)
                {
                    olog.outMensaje("cIfxClientesCon.leer_BytesGuardarBlancoASCII:"+sdireccionipagenete+" Inicio guardar archivo :"+odarchivo.getDestino());
                    olog.outMensaje("cIfxClientesCon.leer_BytesGuardarBlancoASCII:"+sdireccionipagenete+" Tamaño archivo ->"+odarchivo.getTamanoArchivo());
                    int nlen=0;
                    String soriginal="";
                    long nprueba=0;

                    while(((nread = sis.read(buffer))>0))
                    //while(((nread = sis.read(buffer))!=-1))
                    {

                        ntotalleido+=nread;
                        if(ntotalleido>odarchivo.getTamanoArchivo())
                        {
                            nread=nread-(int)(ntotalleido-odarchivo.getTamanoArchivo());
                            //int ndiff=quitarCRNL(buffer);
                            stmp=new String(buffer,"UTF8");
                            //Esto es una prueba
                            stmp=stmp.replaceAll("\r\n", " \n");
                            //nread=stmp.getBytes("UTF8").length;
                            //if(ndiff>0)
                            //    nread=nread-ndiff;
                            fout.write(stmp.getBytes("UTF8"),0,nread);
                            scadenaperdida=stmp.substring(nread+1);
                            fout.flush();
                            lout.println("IFX-putASCII TERMENI");

                            break;
                        }
                        else if(ntotalleido==odarchivo.getTamanoArchivo())
                        {
                            //int ndiff=quitarCRNL(buffer);
                            stmp=new String(buffer,"UTF8");
                            //Esto es una prueba
                            stmp=stmp.replaceAll("\r\n", " \n");
                            //nread=stmp.getBytes("UTF8").length;
                            //if(ndiff>0)
                            //    nread=nread-ndiff;
                            fout.write(stmp.getBytes("UTF8"),0,nread);
                            //fout.write(stmp.getBytes("UTF8"));
                            //fout.write(buffer,0,nread);
                            fout.flush();
                            lout.println("IFX-putASCII TERMENI");
                            break;
                        }
                        else
                        {
                            //int ndiff=quitarCRNL(buffer);
                            stmp=new String(buffer,"UTF8");
                            //Esto es una prueba
                            stmp=stmp.replaceAll("\r\n", " \n");
                            //nread=stmp.getBytes("UTF8").length;
                            //if(ndiff>0)
                            //    nread=nread-ndiff;
                            fout.write(stmp.getBytes("UTF8"),0,nread);
                        }
                        //Limpiando Buffer de datos para dejar en vacio.
                        buffer=new byte[ntamanoenvio];

                    }
                    lout.flush();
                    //fout.flush();

                    olog.outMensaje("cIfxClientesCon.leer_BytesGuardarBlancoASCII:"+sdireccionipagenete+" FIN LEER Total Leido ->"+ntotalleido);
                    olog.outMensaje("cIfxClientesCon.leer_BytesGuardarBlancoASCII:"+sdireccionipagenete+" TAMAÑO Archivo Total Leido ->"+odarchivo.getTamanoArchivo());
                    //System.out.println("leerGuardarBytes - Termina guardar archivo");

                    //sis.close();
                    //lout.close();
                    //lin.close();
                }
                fout.close();
        } catch (IOException ex) {
            //Logger.getLogger(cIfxClientesCon.class.getName()).log(Level.SEVERE, null, ex);
            olog.outMensaje("cIfxClientesCon.leer_BytesGuardarBlancoASCII(): ERROR:"+ex.getMessage());
        }
    }
    /**
     * Lee los archivos que envian desde los clientes
     * cuando se llama Put.
     * Hace el cambio de "\r\n" por "\n"
     */
    protected synchronized void leer_BytesGuardarASCII()
    {
                InputStream sis;
        String stmp="";
        try {
                sis = puerto.getInputStream();

                PrintWriter lout = new PrintWriter(puerto.getOutputStream(), true);
                //BufferedReader lin = new BufferedReader(new InputStreamReader(puerto.getInputStream()));

                byte[] buffer=new byte[ntamanoenvio];
                int nread=0;
                long ntotalleido=0;
                OutputStream fout = null;
                //String sSalir="";
                //Manejo de archivo en disco
                //Encoder.UTF_8;
                //InputStreamReader reader = new InputStreamReader
                        
                File fdestino = new File(odarchivo.getDestino());
                if(fdestino.exists())
                {
                        //Si el archivo existe abrirlo para agregar lo que falta
                        //si el tamaño del archivo es igual al que se va a transmitir?
                        //salir archivo ya existe y no se hace nada
                    if(fdestino.length()>=odarchivo.getTamanoArchivo())
                    {
                        //lout.println("IFX-putASCII existe");
                        olog.outMensaje("cIfxClientesCon.leer_BytesGuardarASCII:"+sdireccionipagenete+" YA EXISTE el archivo: "+odarchivo.getDestino());
                        //sis.close();
                        //lout.close();
                        //fout.close();
                        //return;
                        moverArchivoViejo(odarchivo.getDestino());
                        fdestino = new File(odarchivo.getDestino());
                    }
                    olog.outMensaje("cIfxClientesCon.leer_BytesGuardarASCII:"+sdireccionipagenete+" YA EXISTE el archivo pero incompleto: "+odarchivo.getDestino());
                    olog.outMensaje("cIfxClientesCon.leer_BytesGuardarASCII:"+sdireccionipagenete+" El tamaño actual es: "+fdestino.length());

                    fout = new FileOutputStream(fdestino,true);
                    lout.println("IFX-putASCII tamano:"+fdestino.length());
                    //Aqui me aseguro que el tamaño donde arranco es el del actual archivo
                    ntotalleido=fdestino.length();
                    //fdestino.

                }
                else
                {
                     fout = new FileOutputStream(fdestino,true);
                     lout.println("IFX-putASCII tamano:0");

                }
                //OutputStream fout = new FileOutputStream(fdestino,true);
                lout.flush();    
                if(odarchivo.getTamanoArchivo()>0)
                {
                    olog.outMensaje("cIfxClientesCon.leer_BytesGuardarASCII:"+sdireccionipagenete+" Inicio guardar archivo :"+odarchivo.getDestino());
                    olog.outMensaje("cIfxClientesCon.leer_BytesGuardarASCII:"+sdireccionipagenete+" Tamaño archivo ->"+odarchivo.getTamanoArchivo());
                    int nlen=0;
                    String soriginal="";
                    long nprueba=0;

                    while(((nread = sis.read(buffer))>0))
                    //while(((nread = sis.read(buffer))!=-1))
                    {

                        ntotalleido+=nread;
                        if(ntotalleido>odarchivo.getTamanoArchivo())
                        {
                            nread=nread-(int)(ntotalleido-odarchivo.getTamanoArchivo());
                            int ndiff=quitarCRNL(buffer);
                            stmp=new String(buffer,"UTF8");
                            //Esto es una prueba
                            stmp=stmp.replaceAll("\r\n", "\n");
                            //nread=stmp.getBytes("UTF8").length;
                            if(ndiff>0)
                                nread=nread-ndiff;
                            fout.write(stmp.getBytes("UTF8"),0,nread);
                            scadenaperdida=stmp.substring(nread+1);
                            fout.flush();
                            lout.println("IFX-putASCII TERMENI");

                            break;
                        }
                        else if(ntotalleido==odarchivo.getTamanoArchivo())
                        {
                            int ndiff=quitarCRNL(buffer);
                            stmp=new String(buffer,"UTF8");
                            //Esto es una prueba
                            stmp=stmp.replaceAll("\r\n", "\n");
                            //nread=stmp.getBytes("UTF8").length;
                            if(ndiff>0)
                                nread=nread-ndiff;
                            fout.write(stmp.getBytes("UTF8"),0,nread);
                            //fout.write(stmp.getBytes("UTF8"));
                            //fout.write(buffer,0,nread);
                            fout.flush();
                            lout.println("IFX-putASCII TERMENI");
                            break;
                        }
                        else
                        {
                            int ndiff=quitarCRNL(buffer);
                            stmp=new String(buffer,"UTF8");
                            //Esto es una prueba
                            stmp=stmp.replaceAll("\r\n", "\n");
                            //nread=stmp.getBytes("UTF8").length;
                            if(ndiff>0)
                                nread=nread-ndiff;
                            fout.write(stmp.getBytes("UTF8"),0,nread);
                        }
                        //Limpiando Buffer de datos para dejar en vacio.
                        buffer=new byte[ntamanoenvio];

                    }
                    lout.flush();
                    //fout.flush();

                    olog.outMensaje("cIfxClientesCon.leer_BytesGuardarASCII:"+sdireccionipagenete+" FIN LEER Total Leido ->"+ntotalleido);
                    olog.outMensaje("cIfxClientesCon.leer_BytesGuardarASCII:"+sdireccionipagenete+" TAMAÑO Archivo Total Leido ->"+odarchivo.getTamanoArchivo());
                    //System.out.println("leerGuardarBytes - Termina guardar archivo");

                    //sis.close();
                    //lout.close();
                    //lin.close();
                }
                fout.close();
        } catch (IOException ex) {
            //Logger.getLogger(cIfxClientesCon.class.getName()).log(Level.SEVERE, null, ex);
            olog.outMensaje("cIfxClientesCon.leer_BytesGuardarASCII(): ERROR:"+ex.getMessage());
        }
    }
   
     /**
     * Esta fucion mueve un archivo a otro nombre
     * archivo.ext# donde # inicia en 1 hasta n
     * @param paharchivo 
     */
    protected synchronized void moverArchivoViejo(String paharchivo)
    {
        try{
            File oldfile = new File(paharchivo);
            File newfile = new File(paharchivo);
            int nconse=1;
            while(newfile.exists())
            {
                newfile = new File(paharchivo+nconse);
                nconse++;

            }


            oldfile.renameTo(newfile);
        }
        catch (Exception ex)
        {
            olog.outMensaje("cIfxClientesCon.moverArchivoViejo(): ERROR:"+ex.getMessage());
        }
    }
    /**
     * Esta es nueva funcion en ella intento probar como hacer
     * para enviar el resultado de lo que ya esta guardado
     * la diferencia importante es que esta funcion incluye el envio
     * del msg "IFX-Put TERMENI"
     * para indicar que ya termino de leer el archivo y avisar para que pare el flujo de datos
     * al cliente
     */
    protected synchronized void leer_BytesGuardar() 
    {
        InputStream sis;
        String stmp="";
        try {
                sis = puerto.getInputStream();

                PrintWriter lout = new PrintWriter(puerto.getOutputStream(), true);
                //BufferedReader lin = new BufferedReader(new InputStreamReader(puerto.getInputStream()));

                byte[] buffer=new byte[ntamanoenvio];
                int nread=0;
                long ntotalleido=0;
                OutputStream fout = null;
                //String sSalir="";
                //Manejo de archivo en disco
                //Encoder.UTF_8;
                //InputStreamReader reader = new InputStreamReader
                        
                File fdestino = new File(odarchivo.getDestino());
                if(fdestino.exists())
                {
                        //Si el archivo existe abrirlo para agregar lo que falta
                        //si el tamaño del archivo es igual al que se va a transmitir?
                        //salir archivo ya existe y no se hace nada
                    if(fdestino.length()>=odarchivo.getTamanoArchivo())
                    {
                        //lout.println("IFX-Put existe");
                        olog.outMensaje("cIfxClientesCon.leer_BytesGuardar:"+sdireccionipagenete+" YA EXISTE el archivo: "+odarchivo.getDestino());
                        //sis.close();
                        //lout.close();
                        //fout.close();
                        //return;
                        moverArchivoViejo(odarchivo.getDestino());
                        fdestino = new File(odarchivo.getDestino());
                        
                    }
                    olog.outMensaje("cIfxClientesCon.leer_BytesGuardar:"+sdireccionipagenete+" YA EXISTE el archivo pero incompleto: "+odarchivo.getDestino());
                    olog.outMensaje("cIfxClientesCon.leer_BytesGuardar:"+sdireccionipagenete+" El tamaño actual es: "+fdestino.length());

                    fout = new FileOutputStream(fdestino,true);
                    lout.println("IFX-Put tamano:"+fdestino.length());
                    //Aqui me aseguro que el tamaño donde arranco es el del actual archivo
                    ntotalleido=fdestino.length();
                    //fdestino.

                }
                else
                {
                     fout = new FileOutputStream(fdestino,true);
                     lout.println("IFX-Put tamano:0");

                }
                //OutputStream fout = new FileOutputStream(fdestino,true);
                lout.flush();
                if(odarchivo.getTamanoArchivo()>0)
                {
                    olog.outMensaje("cIfxClientesCon.leer_BytesGuardar:"+sdireccionipagenete+" Inicio guardar archivo :"+odarchivo.getDestino());
                    olog.outMensaje("cIfxClientesCon.leer_BytesGuardar:"+sdireccionipagenete+" Tamaño archivo ->"+odarchivo.getTamanoArchivo());
                    int nlen=0;
                    String soriginal="";
                    long nprueba=0;

                    while(((nread = sis.read(buffer))>0))
                    //while(((nread = sis.read(buffer))!=-1))
                    {

                        ntotalleido+=nread;
                        if(ntotalleido>odarchivo.getTamanoArchivo())
                        {
                            nread=nread-(int)(ntotalleido-odarchivo.getTamanoArchivo());
                            //stmp=new String(buffer,"UTF8");
                            fout.write(buffer,0,nread);
                            scadenaperdida=stmp.substring(nread+1);
                            fout.flush();
                            lout.println("IFX-Put TERMENI");

                            break;
                        }
                        else if(ntotalleido==odarchivo.getTamanoArchivo())
                        {
                            //stmp=new String(buffer,"UTF8");
                            fout.write(buffer,0,nread);
                            fout.flush();
                            lout.println("IFX-Put TERMENI");
                            break;
                        }
                        else
                        {
                            //stmp=new String(buffer,"UTF8");
                            fout.write(buffer,0,nread);
                        }
                        //Limpiando Buffer de datos para dejar en vacio.
                        buffer=new byte[ntamanoenvio];
                        

                    }
                    lout.flush();
                    //fout.flush();

                    olog.outMensaje("cIfxClientesCon.leer_BytesGuardar:"+sdireccionipagenete+" FIN LEER Total Leido ->"+ntotalleido);
                    olog.outMensaje("cIfxClientesCon.leer_BytesGuardar:"+sdireccionipagenete+" TAMAÑO Archivo Total Leido ->"+odarchivo.getTamanoArchivo());
                    //System.out.println("leerGuardarBytes - Termina guardar archivo");

                    //sis.close();
                    //lout.close();
                    //lin.close();
                }
                fout.close();
                
        } catch (IOException ex) {
            //Logger.getLogger(cIfxClientesCon.class.getName()).log(Level.SEVERE, null, ex);
            olog.outMensaje("cIfxClientesCon.leer_BytesGuardar(): ERROR:"+ex.getMessage());
        }
        catch(Exception ex)
        {
           olog.outMensaje("cIfxClientesCon.leer_BytesGuardar(): ERROR:"+ex.getMessage()); 
        }
    }
    /**
     * 
     * @param datos
     * @return , direfencia de los bytes que se quitan de la cadena
     */
    protected int quitarCRNL(byte[] datos)
    {
        int nnuevotam=0;
        try {
            String soldcadena = new String(datos,"UTF8");
            String snewcadena = new String(datos,"UTF8");
            
            soldcadena=soldcadena.replaceAll("\r\n", "\n");
            
            nnuevotam= (snewcadena.length()-soldcadena.length());
            return nnuevotam;
            
        } catch (UnsupportedEncodingException ex) {
            
            olog.outMensaje("cIfxClientesCon.quitarCRNL(): ERROR:"+ex.getMessage());
            return 0;
        }
        
        
    }
    protected void _leerGuardarBytes() 
    {
        InputStream sis;
        String stmp="";
        try {
                sis = puerto.getInputStream();

                PrintWriter lout = new PrintWriter(puerto.getOutputStream(), true);
                //BufferedReader lin = new BufferedReader(new InputStreamReader(puerto.getInputStream()));

                byte[] buffer=new byte[ntamanoenvio];
                int nread=0;
                long ntotalleido=0;
                OutputStream fout = null;
                //String sSalir="";
                //Manejo de archivo en disco
                File fdestino = new File(odarchivo.getDestino());
                if(fdestino.exists())
                {
                        //Si el archivo existe abrirlo para agregar lo que falta
                        //si el tamaño del archivo es igual al que se va a transmitir?
                        //salir archivo ya existe y no se hace nada
                    if(fdestino.length()>=odarchivo.getTamanoArchivo())
                    {
                        lout.println("IFX-Put existe");
                        olog.outMensaje("cIfxClientesCon.leerGuardarBytes:"+sdireccionipagenete+" YA EXISTE el archivo: "+odarchivo.getDestino());
                        //sis.close();
                        //lout.close();
                        //fout.close();
                        return;
                    }
                    olog.outMensaje("cIfxClientesCon.leerGuardarBytes:"+sdireccionipagenete+" YA EXISTE el archivo pero incompleto: "+odarchivo.getDestino());
                    olog.outMensaje("cIfxClientesCon.leerGuardarBytes:"+sdireccionipagenete+" El tamaño actual es: "+fdestino.length());

                    fout = new FileOutputStream(fdestino,true);
                    lout.println("IFX-Put tamano:"+fdestino.length());
                    //fdestino.

                }
                else
                {
                     fout = new FileOutputStream(fdestino,true);
                     lout.println("IFX-Put tamano:0");

                }
                //OutputStream fout = new FileOutputStream(fdestino,true);
                lout.flush();    
                olog.outMensaje("cIfxClientesCon.leerGuardarBytes:"+sdireccionipagenete+" Inicio guardar archivo :"+odarchivo.getDestino());
                olog.outMensaje("cIfxClientesCon.leerGuardarBytes:"+sdireccionipagenete+" Tamaño archivo ->"+odarchivo.getTamanoArchivo());
                int nlen=0;

                while(((nread = sis.read(buffer))>0))
                //while(((nread = sis.read(buffer))!=-1))
                {
//                    if(buffer.toString().contains("IFX-EOF-EOF"))
//                    {
//                        stmp=buffer.toString();
//                        stmp=stmp.substring(0,stmp.indexOf("IFX-EOF-EOF"));
//                        buffer = stmp.getBytes();
//                        nread = buffer.length;
//                    }
                    ntotalleido+=nread;
                    if(ntotalleido>odarchivo.getTamanoArchivo())
                    {
                        nread=nread-(int)(ntotalleido-odarchivo.getTamanoArchivo());
                        stmp=new String(buffer);
                        scadenaperdida=stmp.substring(nread+1);
                        fout.write(buffer,0,nread);
                        break;
                    }
                    
                    //Escribiendo Archivo
                    fout.write(buffer,0,nread);
                    //fout.flush();
                    

                    //System.out.println(ntotalleido+" "+odarchivo.getTamanoArchivo());

                }
                
                fout.flush();

                olog.outMensaje("cIfxClientesCon.leerGuardarBytes:"+sdireccionipagenete+" FIN LEER Total Leido ->"+ntotalleido);
                olog.outMensaje("cIfxClientesCon.leerGuardarBytes:"+sdireccionipagenete+" TAMAÑO Archivo Total Leido ->"+odarchivo.getTamanoArchivo());
                //System.out.println("leerGuardarBytes - Termina guardar archivo");

                //sis.close();
                //lout.close();
                //lin.close();
                fout.close();
        } catch (IOException ex) {
            //Logger.getLogger(cIfxClientesCon.class.getName()).log(Level.SEVERE, null, ex);
            olog.outMensaje("cIfxClientesCon.leerGuardarBytes(): ERROR:"+ex.getMessage());
        }
    }
    protected synchronized void CopiarArchivo(String aorigen, String adestino)
    {
        // Copiar ficheros
        File origen = new File(aorigen);
        File destino = new File(adestino);

        try {
          InputStream in = new FileInputStream(origen);
          OutputStream out = new FileOutputStream(destino);

          byte[] buf = new byte[1024];
          int len;

          while ((len = in.read(buf)) > 0) {
            out.write(buf, 0, len);
          }

          in.close();
          out.close();
        } catch (IOException ioe){
          ioe.printStackTrace();
        }
    }
    
    /**
     * Funciona para leer el archivo del disco y enviarlo al Cliente
     * @param snombrearchivo, nombreArchivo
     * @param spathdestino , laruta donde se deben guardar los datos en el destino
     * @param spathorigen , El origen del archivo 
     */
    protected synchronized void leerEnviarBytes(String sorigen,  Socket socket)
    {
        OutputStream sout;
        //InputStream fin;
        RandomAccessFile rfin;
        BufferedReader brin;
        String sentrada="";
        long ntotalenviado=0;
        byte[] buff= new byte[ntamanoenvio];
        int len;
        long ninicioread = 0;
        odarchivo.setOrigen(sorigen);
        odarchivo.setDestino("NULL");
        odarchivo.setTamanoTransmit(ntamanoenvio);
       
        
        
      
        olog.outMensaje("cIfxClientesCon.leerEnviarBytes: Cargando el File java: "+odarchivo.getOrigen());
        //olog.outMensaje("cifxCliente: Conectado ("+direccion+":"+String.valueOf(puerto)+")");
        File forigen = new File(odarchivo.getOrigen());
      
        
        if(forigen.exists())
        {
            odarchivo.setTamanoArchivo(forigen.length());
            /*try {
                sout = socket.getOutputStream();
                
            } catch (IOException ex) {
                Logger.getLogger(cifxCliente.class.getName()).log(Level.SEVERE, null, ex);
            }*/
            try {
                
                //fin = new FileInputStream(forigen);
                olog.outMensaje("cIfxClientesCon.leerEnviarBytes: Abriendo archivo random :");
                rfin = new RandomAccessFile(forigen, "rw");
                sout = socket.getOutputStream();
                //
                brin = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                
                //pout.write("IFX-Put "+odarchivo.aCadena());
                //pout.println("IFX-Put "+odarchivo.aCadena());
                sout.write(("IFX-Get "+odarchivo.aCadena()+"\n").getBytes());
                //sentrada=brin.readLine();
                sentrada=brin.readLine();
                
                if(sentrada.contains("IFX-Get existe"))
                {
                    olog.outMensaje("cIfxClientesCon.leerEnviarBytes: Ya existe en el cliente el archivo: "+odarchivo.getDestino());
                    //pout.println("IXF-Desconectar");
                    //sout.write(("IXF-Desconectar\n").getBytes());
                    //rfin.close();
                    //sout.close();
                    ninicioread=odarchivo.getTamanoArchivo();
                    //return;
                }
                else if(sentrada.contains("IFX-Get tamano:"))
                {
                    ninicioread= Long.parseLong(quitarPalabra(sentrada,"IFX-Get tamano:"));
                }

                //En caso de que el tamaño del archivo sea 0 no se ejecuta nada
                if(odarchivo.getTamanoArchivo()>0)
                {
                    //
                    olog.outMensaje("cIfxClientesCon.leerEnviarBytes: INICIO Envio archivo de tamaño :"+odarchivo.getTamanoArchivo());
                    olog.outMensaje("cIfxClientesCon.leerEnviarBytes: El envio inicia a partir de :"+ (ninicioread));

                    rfin.seek(ninicioread);
                    String stmp="";

                    while((len = rfin.read(buff))>=0)
                    {
                        //stmp=new String(buff,"UTF8");
                        //sout.write(stmp.getBytes("UTF8"),0,len);
                        sout.write(buff,0,len);
                        ntotalenviado+= len;
                        sout.flush();
                        //System.out.print("*");
                    }
                    //sout.write((int)'\n');

                    sentrada=brin.readLine();
                    if(sentrada.equals("IFX-Get TERMENI"))
                    {
                        sout.flush();
                        olog.outMensaje("leerEnviarBytes: TERMINO - Total enviado ->"+ntotalenviado);

                        rfin.close();
                    }
                    else
                        olog.outMensaje("leerEnviarBytes: ERROR - Total enviado ->"+ntotalenviado);
                }
                
            } 
            catch (FileNotFoundException ex) {
                //Logger.getLogger(cifxCliente.class.getName()).log(Level.SEVERE, null, ex);
                olog.outMensaje("cIfxClientesCon.leerEnviarBytes(): FileNotFoundException"+ex.getMessage());
            }
            catch (IOException ex) {
                //Logger.getLogger(cifxCliente.class.getName()).log(Level.SEVERE, null, ex);
                olog.outMensaje("cIfxClientesCon.leerEnviarBytes(): IOException"+ex.getMessage());
            }
            
            
            
        }
        else
        {
            try {
                olog.outMensaje("cIfxClientesCon.leerEnviarBytes(): Archivo no existe en el servidor");
                socket.getOutputStream().write(("IFX-Get NOEXISTE").getBytes());
            } catch (IOException ex) {
                olog.outMensaje("cIfxClientesCon.leerEnviarBytes(): IOException"+ex.getMessage());
            }
            
        }
        
        
        
    }
     
    /**
     * Funcion para quitar una palabra al principio de una frase
     * @param sfrase, la frase que contiene la palabra a quitar
     * @param spalabra, la palabra que se quitara de la frase
     * @return 
     */
    protected String quitarPalabra(String sfrase, String spalabra)
    {
        String ssalida="";
        int nstart = sfrase.indexOf(spalabra)+spalabra.length();
        ssalida = sfrase.substring(nstart);
        return ssalida;

    }

}
